package com.fierce.cloud.ota.controller;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import cn.hutool.core.util.ZipUtil;
import com.fierce.cloud.core.web.ResultGenerator;
import com.fierce.cloud.core.web.responseDto.Response;
import com.fierce.cloud.ota.model.VersionInfo;
import com.fierce.cloud.ota.service.AppInfoService;
import com.fierce.cloud.ota.service.VersionInfoService;
import com.fierce.cloud.utils.FileSearchUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletResponse;

/**
 * @author: Fierce
 * @Date: 2021/2/23 11:31
 */
@RestController
@RequestMapping("/version")
@Slf4j
public class VersionController {

    @Autowired
    VersionInfoService versionInfoService;

    @Autowired
    AppInfoService appInfoService;

    List<String> zipExtensionName = new ArrayList<String>() {
        {
            this.add(".rar");
            this.add(".zip");
        }
    };

    List<String> canPreviewExtensionName = new ArrayList<String>() {
        {
            this.add(".html");
            this.add(".txt");
            this.add(".png");
            this.add(".jpg");
            this.add(".jpeg");
        }
    };

    /**
     * 更新版本信息
     *
     * @param versionInfo
     * @return
     */
    @PostMapping("/info/update")
    public Response updateVersionInfo(VersionInfo versionInfo) {
        versionInfoService.update(versionInfo);
        return ResultGenerator.genSuccessResult("更新成功");
    }

    @DeleteMapping("/{versionId}")
    public Response deleteVersionById(@PathVariable Integer versionId) {
        versionInfoService.deleteById(versionId);
        return ResultGenerator.genSuccessResult("删除版本成功");
    }

    /**
     * 分页查询版本信息
     *
     * @param appId
     * @return
     */
    @GetMapping("/list")
    public Response<List<VersionInfo>> listVersion(Long appId) {

        Example example = new Example(VersionInfo.class);
        example.createCriteria().andEqualTo("appId", appId);
        List<VersionInfo> versionInfoList = versionInfoService.findByExample(example);
        versionInfoList = versionInfoList.stream().peek(versionInfo -> {
            String previewUrl = versionInfo == null ? "" : versionInfo.getStorageUrl();
            File previewDirectory = new File("upload/web");
            if (previewUrl.contains(previewDirectory.getAbsolutePath())) {
                previewUrl = previewUrl.replace(previewDirectory.getAbsolutePath(), "");
                previewUrl = previewUrl.replace("\\", "/");
                versionInfo.setStorageUrl(previewUrl);
            } else {
                versionInfo.setStorageUrl("");
            }
        }).collect(Collectors.toList());
        versionInfoList = versionInfoList.stream().sorted(Comparator.comparing(VersionInfo::getUploadTime).reversed()).collect(Collectors.toList());
        return ResultGenerator.genSuccessResult(versionInfoList);
    }

    /**
     * 版本上传接口
     *
     * @param versionCode   版本号
     * @param versionName   版本名
     * @param modifyContent 修改内容
     * @param file          版本文件
     * @return
     */
    @PostMapping("/upload")
    @Transactional(rollbackFor = Exception.class)
    public Response uploadVersion(Long appId, Integer versionCode, String versionName, String modifyContent, Long uploaderId, MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename();
        String extensionName = originalFilename.substring(originalFilename.lastIndexOf("."));
        String prePackageName = file.getOriginalFilename() + versionName + versionCode + modifyContent + uploaderId.toString();
        prePackageName = DigestUtils.md5DigestAsHex(prePackageName.getBytes());
        String packageName = prePackageName + extensionName;
        String filePath = versionInfoService.versionUpload(packageName, file);
        VersionInfo versionInfo = new VersionInfo();
        versionInfo.setAppId(appId);
        versionInfo.setVersionCode(versionCode);
        versionInfo.setVersionName(versionName);
        versionInfo.setModifyContent(modifyContent);
        versionInfo.setDownloadUrl("/version/download/" + packageName);
        versionInfo.setSize(file.getSize());
        versionInfo.setUploaderId(uploaderId);
        try {
            if (zipExtensionName.contains(extensionName)) {
                File unzipPath = new File("upload/web/" + prePackageName);
                if (!unzipPath.exists()) {
                    unzipPath.mkdirs();
                }
                File unzip = ZipUtil.unzip(filePath, unzipPath.getAbsolutePath());
                List<File> files = FileSearchUtil.searchFiles(unzip.getAbsoluteFile(), "index.html");
                if (files.size() > 0) {
                    versionInfo.setStorageUrl(files.get(0).getAbsolutePath());
                } else {
                    versionInfo.setStorageUrl(filePath);
                }
            } else {
                versionInfo.setStorageUrl(filePath);
            }
            if (canPreviewExtensionName.contains(extensionName)) {
                File previewFile = new File("upload/web/" + prePackageName);
                if (!previewFile.exists()) {
                    previewFile.mkdirs();
                }
                FileCopyUtils.copy(new File(filePath), new File("upload/web/" + packageName));
                versionInfo.setStorageUrl(new File("upload/web/" + packageName).getAbsolutePath());
            }
        } catch (Exception e) {
            log.info(e.getMessage());
            versionInfo.setStorageUrl(filePath);
        }
        versionInfoService.save(versionInfo);
        return ResultGenerator.genSuccessResult("版本上传成功");
    }

    /**
     * 版本下载接口
     *
     * @param response
     * @param name     下载文件Name
     */
    @GetMapping("/download/{name}")
    public void downloadVersion(HttpServletResponse response, @PathVariable String name) {
        versionInfoService.versionDownload(name, response);
    }

}
